//***********************************************************
//*
//* File:           DumbPlayer.java
//* Author:         Abhinav Kamra
//* Contact:        kamra@cs.columbia.edu
//* Update:         10/03/2004
//*
//* Description:    Dump player for Project 2.  Purely for
//*                 didactic purposes.
//*
//***********************************************************

package paths.g4;

import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;

import paths.*;
import paths.g4.*;

public final class P22 implements IFCPlayer {

  static Random _random;
  static final String _CNAME = "G4 Player2";
  static final Color  _CCOLOR = new Color(0.8f, 0.2f, 0.4f);

  Maps _maps;
  ArrayList<City> cities;
  ArrayList<Link> links;
  boolean[][] reachable_links;
  String start_city_name;
  int start_city_idx;
  City start_city;
  int in_degree[];
  int out_degree[];
  int num_city;

  public void register(Maps __maps) throws Exception {
    _maps = __maps;
    cities = _maps.getCities();
    links = _maps.getLinks();
    num_city = cities.size();
    in_degree = new int[num_city];
    out_degree = new int[num_city];
  }

  public Move move() throws Exception {
    BufferedImage image;

    //File file = _maps.getBackgroundImage();
    File file = new File("GameFiles/G4-with-map.png");

    //to get the background image, do this
    image = ImageIO.read(file);

    //get graphics to draw on the image.
    Graphics2D g = image.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_ON);

    // Search the graph
    start_city_name = _maps.getStart().name;
    start_city_idx = Util.getCityIdxByName(start_city_name, cities);
    start_city = cities.get(start_city_idx);
    reachable_links =
        Util.FindAllPossibleRoutes(cities, links, start_city_name);
    Util.removeShortRoutes(reachable_links, start_city_idx);

    
  //change
  /*  int tt=0;
    boolean reachable[][]=new boolean[num_city][num_city];
    for(int k=0;k<num_city;k++)
    {
    	for(int c=0;c<num_city;c++)
        {
    	reachable[k][c]=false;
    }
    }
    System.out.println("check this");
    for(int t=0;t<cities.size();t++)
    {
    	 for(int l=0;l<cities.size();l++)
    	    {
    		 for(int m=0;m<cities.size();m++)
    		    {
    		    	reachable[l][m]=(reachable_links[l][m]||(reachable_links[l][t] && reachable_links[t][m]));
    		    }	
    	    }
    }*/
    int pp=0;
    for(int cc=0;cc<num_city;cc++)
    {
	if(in_degree[cc]>0)
	{
		pp++;
	}
}
    /*	
    if(reachable_links[t][start_city_idx])
    	{
    tt++;
    		reachable[t]=true;
    		for(int j=0;j<cities.size();j++)
    		{
    			if(reachable_links[t][j])
    		                      {
    				if(!reachable[j])
    				{
    				reachable[j]=true;
    				tt++;
    				}                 }
    			
    		}
    		System.out.print(cities.get(t).name);
    	}
    }*/
    System.out.println("check finished in degree " +pp );
    //change
    
    drawGraph((Graphics2D) g.create(18, 246, graph_width, graph_height));
    drawExampleRoutes(
        (Graphics2D) g.create(18, 10, page_width, example_route_height));

    Move RET = new Move(image, "Dumb World Map");
    return RET;
  }

  private String routeToString(ArrayList<Integer> route) {
    String route_str = "";
    final int OMIT_THRESHOLD = 7;
    if (route.size() <= OMIT_THRESHOLD) {
      for (Integer i : route) {
        route_str += cities.get(i).name + " -> ";
      }
    } else {
      for (int i = 0; i < 2; i++)
        route_str += cities.get(route.get(i)).name + " -> ";
      route_str += " (" + (route.size() - OMIT_THRESHOLD + 2) + " more cities) -> ";
      for (int i = route.size() - OMIT_THRESHOLD + 3 + 2; i < route.size(); i++)
        route_str += cities.get(route.get(i)).name + " -> ";
    }
    route_str += start_city_name;
    return route_str;
  }

  private void drawExampleRoutes(Graphics2D g) {
    ArrayList<Integer> longest_route =
        Util.findLongestRoute(cities, reachable_links, start_city_idx);
    String longest_route_str = routeToString(longest_route);

    ArrayList<City> routee=new ArrayList<City>();
    for (int i = 0; i < longest_route.size() ; i++) {
        routee.add(cities.get(longest_route.get(i)));
    }
    String descript=CityMetadata.getMetaResult(routee);
    
    g.setColor(Color.RED);
    g.setFont(new Font("SansSerif", Font.BOLD, 18));
    g.drawString("YAL TOURS - ONE TICKET -- ONE PRICE", 15, 15);
    
    
    //g.setColor(Color.WHITE);
    //g.setFont(new Font("SansSerif", Font.BOLD, 18));
    //g.drawString(" OPPORTUNITIES UNLIMITED", 25, 20);
   
    
    g.setColor(Color.WHITE);
    g.setFont(new Font("SansSerif", Font.BOLD, 12));
    g.drawString("Longest Route and "+descript, 5, 35);
    g.setFont(new Font("SansSerif", Font.PLAIN, 12));
    g.drawString(longest_route_str, 5, 50);
    for (int n = 0; n < 3; n++) {
      ArrayList<Integer> route =
          Util.FindRandomRoute(reachable_links, start_city_idx);
      while(route.size()<6)
      {
    	  route =
              Util.FindRandomRoute(reachable_links, start_city_idx);
    	  
      }
      ArrayList<City> routeee=new ArrayList<City>();
      for (int i = 0; i < route.size() ; i++) {
          routeee.add(cities.get(route.get(i)));
      }
      String descriptt=CityMetadata.getMetaResult(routeee);
      
      String route_str = routeToString(route);
      g.setFont(new Font("SansSerif", Font.BOLD, 12));
      g.drawString(descriptt, 5, 70 + n * 35);
      g.setFont(new Font("SansSerif", Font.PLAIN, 12));
      g.drawString(route_str, 5, 85 + n * 35);
    }
  }

  private City getCityByName(String name){
    Iterator<City> it = cities.iterator();
    while(it.hasNext()){
      City city = it.next();
      if(name.equalsIgnoreCase(city.name))
        return city;
    }
    return null;
  }

  public String name() throws Exception {
    return _CNAME;
  }

  public Color color() throws Exception {
    return _CCOLOR;
  }

  public boolean interactive() throws Exception {
    return false;
  }        

  int page_width = 560;
  int example_route_height = 170;
  int graph_width = page_width, graph_height= 440;

  public float mapX( float x){
    return (((x + 180 + 360) * graph_width/360 ) % graph_width);
  }

  public float mapY( float y){
    y = (float) (y * Math.PI / 180.0);
    double normalized = Math.log(Math.tan(Math.PI / 4 + y / 2));
    //double CUT = Math.PI;
    double CUT = 2;
    double projection = (-normalized + CUT) * (graph_height / (2 * CUT));
    return (float) projection;
  }

  private void drawGraph(Graphics2D g) {
    g.setFont(new Font(g.getFont().getName(), Font.BOLD, 10));
    g.setColor(Color.DARK_GRAY);
    Iterator<City> itCity = cities.iterator();
    int num_city = cities.size();
    for (int i = 0; i < num_city; i++) {
      for (int j = 0; j < num_city; j++) {
        if (reachable_links[i][j]) {
          City src = cities.get(i);
          City dest = cities.get(j);
          g.drawLine((int)mapX(src.x), (int)mapY(src.y), (int)mapX(dest.x), (int)mapY(dest.y));
        }
      }
    }

    while(itCity.hasNext()){
      City city = itCity.next();
      g.setColor(Color.BLACK);
      g.drawOval((int)mapX(city.x) - 1, (int)mapY(city.y) - 1, 2, 2);
      g.setColor(Color.GRAY);
      //g.drawString(city.name, mapX(city.x) + 3, mapY(city.y));		    		
    }

    // Draw the longest route.
    ArrayList<Integer> longest_route =
        Util.findLongestRoute(cities, reachable_links, start_city_idx);
    ArrayList<City> route=new ArrayList<City>();
    for (int i = 0; i < longest_route.size() ; i++) {
        route.add(cities.get(longest_route.get(i)));
    }
    String descript=CityMetadata.getMetaResult(route);
    //longest_route.add(start_city_idx);  // route ends at the start city.
    for (int i = 0; i < longest_route.size() - 1; i++) {
      City src = cities.get(longest_route.get(i));
      City dest = cities.get(longest_route.get(i + 1));
      g.setColor(Color.LIGHT_GRAY);
      g.drawLine((int)mapX(src.x), (int)mapY(src.y), (int)mapX(dest.x), (int)mapY(dest.y));
    }
    for (int i = 0; i < longest_route.size(); i++) {
      City src = cities.get(longest_route.get(i));
      g.setColor(Color.BLACK);
      g.drawOval((int)mapX(src.x) - 2, (int)mapY(src.y) - 2, 4, 4);
      g.drawString(src.name, mapX(src.x) + 3, mapY(src.y));		    		
    }

    g.setColor(Color.WHITE);
    g.drawString(start_city.name, mapX(start_city.x) + 3, mapY(start_city.y));		    		
  }
}
